package com.wes.dsptest.dspcontrol;

import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import com.wes.dsptest.R;
import com.wes.dsptest.data.AudioParam;
import com.xw.repo.BubbleSeekBar;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import cn.flyaudio.dsp.IdspInterface;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link DspConfigFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class DspConfigFragment extends Fragment implements IdspCallBack {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private static View rootView;
    private TextView tvText;

    private static final String TAG = "dspTest";
    private static IdspInterface mdspInterface;

    private static SeekBar sbMICVol;
    private static TextView tvMICVol;
    private static int MicVoldb = 0;

    private static SeekBar sbMICBPFStart;
    private static TextView tvMICBPFStartVal;
    private static int MicBPFStartVal = 0; //默认start 0 - end 24000为关

    private static SeekBar sbMICBPFEnd;
    private static TextView tvMICBPFEndVal;
    private static int MicBPFEndVal = 24000;   //默认start 0 - end 24000为关


    private static SeekBar sbAdc0Vol;
    private static TextView tvAdc0Vol;
    private static int MicAdc0_dbVal = 0;   //默认0 - 范围0 -43

    private static SeekBar sbSpeakerVol;
    private static TextView tvSpeakerVol;
    private static int SpeakerdbVal = 0;   //默认0 - 范围-102 - 84


    private static SeekBar sbLineOutVol;
    private static TextView tvLineOutVol;
    private static int LineOutdbVal = 0;   //默认0 - 范围-102 - 84


    private static SeekBar sbHeadSetVol;
    private static TextView tvHeadSetVol;
    private static int HeadsetdbVal = 0;   //默认0 - 范围-102 - 84

    private static BubbleSeekBar sb_revbMode;
    private static int revbMode = 0;   //默认0 - 范围0-7

    private static int[] MicEQFrq = new int[]{65, 125, 250, 500, 1000, 2000};          //范围 1 - 24000
    private static int[] MicEQ_Q = new int[]{200, 200, 200, 200, 200, 200};           //范围 1 - 1000
    private static int[] MicEQGain = new int[]{0, 0, 0, 0, 0, 0};         //范围 -150 - 150


    private Context context;

    protected VolumeControl control;
    private LinkedHashMap<String, List<Integer>> volMap;
    List<Integer> volList;
    private LinkedHashMap<String, List<Integer>> eqMap;
    List<Integer> eqList;
    private CheckBox cbAdc2Vol;
    private Boolean bAdc2Vol = false;
    private TextView tvAdc0, tvAdc1;
    private VolumeSliderView micVolumeSliderView, headsetVolumeSliderView;


    public DspConfigFragment() {
        // Required empty public constructor
    }


    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @return A new instance of fragment dspConfigFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static DspConfigFragment newInstance(String param1) {
        DspConfigFragment fragment = new DspConfigFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        this.context = context;
        initVolumeData();
        initEQData();
        YgInsideDSPControl.initDSP(context, this);
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
        }

    }

    @Override
    @RequiresApi(api = Build.VERSION_CODES.O)
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (rootView == null)
            rootView = inflater.inflate(R.layout.fragment_dsp_config, container, false);
        // Inflate the layout for this fragment
        initView();
        return rootView;
    }

    @Override
    public void onDestroy() {
        YgInsideDSPControl.CloseDSP();
        super.onDestroy();
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void initView() {
        buildVolUI();
        //Eq init
        buildEQUI();

        Button btQuitFullScreen = rootView.findViewById(R.id.btn_quit_full_screen);
        btQuitFullScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()) {

                    case R.id.btn_quit_full_screen:
                        showSystemBarOnDeviceAc8015(context, true);
                        break;

                }
            }
        });

        cbAdc2Vol = rootView.findViewById(R.id.cb_adc2vol);
        bAdc2Vol = cbAdc2Vol.isChecked();
        cbAdc2Vol.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()) {

                    case R.id.cb_adc2vol:
                        bAdc2Vol = cbAdc2Vol.isChecked();
                        break;

                }
            }
        });

        tvAdc0 = rootView.findViewById(R.id.tv_adc0);
        tvAdc1 = rootView.findViewById(R.id.tv_adc1);

        sb_revbMode = rootView.findViewById(R.id.sb_revbMode);

        sb_revbMode.getConfigBuilder()
                .min(0)
                .max(7)
                .progress(0)
                .sectionCount(8)
                .trackColor(ContextCompat.getColor(getContext(), R.color.color_gray))
                .secondTrackColor(ContextCompat.getColor(getContext(), R.color.color_blue))
                .thumbColor(ContextCompat.getColor(getContext(), R.color.color_blue))
                .showSectionText()
                .sectionTextColor(ContextCompat.getColor(getContext(), R.color.colorPrimary))
                .sectionTextSize(18)
                .showThumbText()
                .touchToSeek()
                .thumbTextColor(ContextCompat.getColor(getContext(), R.color.color_red))
                .thumbTextSize(18)
                .bubbleColor(ContextCompat.getColor(getContext(), R.color.color_red))
                .bubbleTextSize(18)
                .showSectionMark()
                .seekBySection()
                .autoAdjustSectionMark()
                .sectionTextPosition(BubbleSeekBar.TextPosition.BELOW_SECTION_MARK)
                .build();


        sb_revbMode.setCustomSectionTextArray(new BubbleSeekBar.CustomSectionTextArray() {
            @Override
            public SparseArray<String> onCustomize(int sectionCount, SparseArray<String> array) {
                array.clear();
                array.put(0, "off");
                array.put(1, "live");
                array.put(2, "hall");
                array.put(3, "concert");
                array.put(4, "cave");
                array.put(5, "bathroom");
                array.put(6, "arena");
                array.put(7, "church");

                return array;
            }
        });

        sb_revbMode.setOnProgressChangedListener(new BubbleSeekBar.OnProgressChangedListenerAdapter() {
            @Override
            public void onProgressChanged(BubbleSeekBar bubbleSeekBar, int progress, float progressFloat, boolean fromUser) {
            }

            @Override
            public void getProgressOnActionUp(BubbleSeekBar bubbleSeekBar, int progress, float progressFloat) {
            }

            @Override
            public void getProgressOnFinally(BubbleSeekBar bubbleSeekBar, int progress, float progressFloat, boolean fromUser) {
                Log.i(TAG, "revbMode getProgressOnFinally: " + progress);
                if (mdspInterface != null) {
                    revbMode = progress;
                    try {
                        mdspInterface.onMic_reverbMode(revbMode);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

            }
        });

    }


    /** @param show t:展开f隐藏*/
    public static void showSystemBarOnDeviceAc8015(Context context,boolean show){
        Intent intent = new Intent();
        intent.setAction("cn.dsp.statusbarnavi.action");
        intent.setPackage("com.android.systemui");
        intent.putExtra("show", show);
        context.sendBroadcast(intent);
    }

    private void initVolumeData() {

        if (control == null) {
            control = new VolumeControl(context, new Handler());
        }
        volMap = new LinkedHashMap<>();
        volList = new ArrayList<>();
        //adc mic vol
        volList.add(43);
        volList.add(0);
        volList.add(0);
        volMap.put(AudioParam.ADCMIC_VOLUME_NAME, volList);
        //mic vol
        volList = new ArrayList<>();
        volList.add(84);
        volList.add(-102);
        volList.add(0);
        volMap.put(AudioParam.MIC_VOLUME_NAME, volList);
        //Speak vol
        volList = new ArrayList<>();
        volList.add(84);
        volList.add(-102);
        volList.add(0);
        volMap.put(AudioParam.SPEAKER_VOLUME_NAME, volList);
        //LineOut vol
        volList = new ArrayList<>();
        volList.add(84);
        volList.add(-102);
        volList.add(0);
        volMap.put(AudioParam.LINEOUT_VOLUME_NAME, volList);
        //HeadSet vol
        volList = new ArrayList<>();
        volList.add(84);
        volList.add(-102);
        volList.add(0);
        volMap.put(AudioParam.HEADSET_VOLUME_NAME, volList);
    }

    private void initEQData() {
        //freq: 65, 125, 250, 500, 1000, 2000
        //q: 200, 200, 200, 200, 200, 200
        eqMap = new LinkedHashMap<>();
        eqList = new ArrayList<>();
        //band1
        eqList.add(AudioParam.BAND1);
        eqList.add(65);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND1_NAME, eqList);
        //band2
        eqList = new ArrayList<>();
        eqList.add(AudioParam.BAND2);
        eqList.add(125);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND2_NAME, eqList);
        //band3
        eqList = new ArrayList<>();
        eqList.add(AudioParam.BAND3);
        eqList.add(250);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND3_NAME, eqList);
        //band4
        eqList = new ArrayList<>();
        eqList.add(AudioParam.BAND4);
        eqList.add(500);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND4_NAME, eqList);
        //band5
        eqList = new ArrayList<>();
        eqList.add(AudioParam.BAND5);
        eqList.add(1000);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND5_NAME, eqList);
        //band6
        eqList = new ArrayList<>();
        eqList.add(AudioParam.BAND6);
        eqList.add(2000);
        eqList.add(200);
        eqList.add(0);
        eqMap.put(AudioParam.BAND6_NAME, eqList);
    }

    private void buildVolUI() {
        LinearLayout scrollView = rootView.findViewById(R.id.volumelevels);
        final TextView tvVolTitle = new TextView(context);
        tvVolTitle.setText("DSP Volumes:");
        tvVolTitle.setTextSize(30);
        scrollView.addView(tvVolTitle, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        for (HashMap.Entry<String, List<Integer>> entry : volMap.entrySet()) {
            final VolumeSliderView volumeSliderView = new VolumeSliderView(context);
            if(entry.getKey() == AudioParam.MIC_VOLUME_NAME)
            {
                micVolumeSliderView = volumeSliderView;
            }
            else if(entry.getKey() == AudioParam.HEADSET_VOLUME_NAME)
            {
                headsetVolumeSliderView = volumeSliderView;
            }
            scrollView.addView(volumeSliderView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            volumeSliderView.setVolumeName(entry.getKey());
            volumeSliderView.setMaxVolume(entry.getValue().get(0));
            volumeSliderView.setMinVolume(entry.getValue().get(1));
            volumeSliderView.setCurrentVolume(entry.getValue().get(2));
            volumeSliderView.setListener(((dBVal, fromUser) -> {
                if (fromUser) {
                    setVol(entry.getKey(), dBVal);
                    volumeSliderView.updateAC8015ProgressText(dBVal);
                }
            }));
        }
    }

    private void buildEQUI() {
        LinearLayout scrollView = rootView.findViewById(R.id.eqlevels);
        final TextView tvEqTitle = new TextView(context);
        tvEqTitle.setText("DSP equalizer:");
        tvEqTitle.setTextSize(30);
        scrollView.addView(tvEqTitle, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

        for (HashMap.Entry<String, List<Integer>> entry : eqMap.entrySet()) {
            final EqualizerView eqSliderView = new EqualizerView(context);
            scrollView.addView(eqSliderView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            eqSliderView.setName(entry.getKey());
            eqSliderView.setMax(EqualizerView.TYPE_FREQ, 24000);
            eqSliderView.setMin(EqualizerView.TYPE_FREQ, 1);
            eqSliderView.setMax(EqualizerView.TYPE_Q, 1000);
            eqSliderView.setMin(EqualizerView.TYPE_Q, 1);
            eqSliderView.setMax(EqualizerView.TYPE_GAIN, 150);
            eqSliderView.setMin(EqualizerView.TYPE_GAIN, -150);
            eqSliderView.setCurrentVal(EqualizerView.TYPE_FREQ, entry.getValue().get(1));
            eqSliderView.setCurrentVal(EqualizerView.TYPE_Q, entry.getValue().get(2));
            eqSliderView.setCurrentVal(EqualizerView.TYPE_GAIN, entry.getValue().get(3));
            eqSliderView.setListener(((type, val, fromUser) -> {
                if (fromUser) {
                    setEQ(entry.getKey(), type, val);
                    eqSliderView.updateProgressText(type, val);
                }
            }));
        }
    }

    private void setVol(String key, int dBVal) {
        Log.i(TAG, "mdspInterface=" + mdspInterface + " key:" + key + ": " + dBVal + "dB");
        if (mdspInterface == null)
            return;
        if (dBVal < -102 && dBVal > 84)//超过范围
            return;

        try {
            switch (key) {
                case AudioParam.ADCMIC_VOLUME_NAME:
                    if (dBVal >= 0 && dBVal <= 43)
                        mdspInterface.onAdc0_vol(dBVal);
                    break;
                case AudioParam.MIC_VOLUME_NAME:
                    mdspInterface.onMic_vol(dBVal);
                    break;
                case AudioParam.SPEAKER_VOLUME_NAME:
                    mdspInterface.onSpeaker_post_vol(dBVal);
                    break;
                case AudioParam.LINEOUT_VOLUME_NAME:
                    mdspInterface.onLineOut_post_vol(dBVal);
                    break;
                case AudioParam.HEADSET_VOLUME_NAME:
                    mdspInterface.onHeadSet_post_vol(dBVal);
                    break;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    private void setEQ(String key, int type, int val) {
        Log.i(TAG, "mdspInterface=" + mdspInterface + " key:" + key + ": " + " type:" + type + " val:" + val);
        int band = eqMap.get(key).get(0);
        int freq = eqMap.get(key).get(1);
        int qval = eqMap.get(key).get(2);
        int gain = eqMap.get(key).get(3);

        if (mdspInterface == null)
            return;

        switch (type) {
            case EqualizerView.TYPE_FREQ:
                freq = val;
                break;
            case EqualizerView.TYPE_Q:
                qval = val;
                break;
            case EqualizerView.TYPE_GAIN:
                gain = val;
                break;

        }
        Log.i(TAG, "band:" + band + " freq:" + freq + " qval :" + qval + " gain:" + gain);

        try {
            mdspInterface.onMic_EQ(band, freq, qval, gain);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void adcToMicVol(float adc, int vol) {
        tvAdc0.setText(String.valueOf(adc));
        if(bAdc2Vol)
        {
            YgInsideDSPControl.setRecordOutVol(vol);
            micVolumeSliderView.setCurrentVolume(vol);
            micVolumeSliderView.updateAC8015ProgressText(vol);
        }
    }

    @Override
    public void adcToHeadSetVol(float adc, int vol) {
        tvAdc1.setText(String.valueOf(adc));
        if(bAdc2Vol)
        {
            YgInsideDSPControl.setHeadsetVol(vol);
            headsetVolumeSliderView.setCurrentVolume(vol);
            headsetVolumeSliderView.updateAC8015ProgressText(vol);
        }

    }

    @Override
    public void connectServerCallBack(IdspInterface dsp) {
        mdspInterface = dsp;
    }

}